package com.langsin.LoopQueueDemo;
/**
@Auther: MFM
@Date: 2021/8/18 - 08 - 18 - 15:25 
@version: 1.0
*/

public class LoopQueue<E> implements Queue<E>{

    //底层数组
    private E[] data;

    //队首
    private int front;

    //队尾
    private int tail;

    //对内元素数量
    private int size;

    /**
     * 构造函数
     *
     * @param capacity
     */
    public LoopQueue(int capacity) {
        data = (E[]) (new Object[capacity + 1]);
        front = 0;
        tail = 0;
        size = 0;
    }

    public LoopQueue() {
        this(10);//默认容量
    }

    /**
     * 返回容量
     * @return
     */
    public int getCapacity(){
        return data.length-1;//把多余的空间去掉
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return front==tail;
    }

    @Override
    public void enqueue(E e) {
        //队列自动扩容
        if ((tail+1)%data.length==front){
            resize(2*getCapacity());
        }

        data[tail] = e;
        tail = (tail+1)%data.length;//此处如此写，是预防数组后无元素空间，前面有元素空间
        size++;
    }


    @Override
    public E dequeue() {
        if (isEmpty()){
            throw new IllegalArgumentException("循环队列为空，无法执行出队操作");
        }

        E ret = data[front];
        data[front] = null;
        front=(front+1)% data.length;
        size--;

        return ret;
    }

    @Override
    public E getFront() {
        if (isEmpty()){
            throw new IllegalArgumentException("循环队列为空，无队首元素");
        }
        return data[front];
    }

    /**
     * 自动扩容
     * @param newCapacity
     */
    private void resize(int newCapacity){
        E[] newData = (E[])(new Object[newCapacity+1]);
        for (int i = 0; i < size; i++) {
            newData[i] = data[(front+i)% data.length];
        }
        data = newData;
        front = 0;
        tail = size;
    }
}
